package SentenceTranslator;

import Include.ASMConstructor;
import Common.REG;
import Include.TACLine;
import Common.TacOperandType;
import Common.RelacedEeg;
import Common.POSTYPE;

import java.util.ArrayList;
import java.util.List;

import Main.SymbolManager;

public class AssignTranslator {

    public List<String> ASMLines;

    public List<String> SentenceTranslate(SymbolManager SymbolManager_, TACLine TACLine_) {
        ASMLines = new ArrayList<String>();
        String str_dst_encode = SymbolManager_.encodeVar(TACLine_.dst.value);
        POSTYPE pos_dst = SymbolManager_.position(str_dst_encode);
        RelacedEeg replaced_reg = null;
        REG dst_reg = SymbolManager_.getReg(str_dst_encode, "");
        if (dst_reg == REG.Cnts) {
            replaced_reg = SymbolManager_.getReplacedReg();
            dst_reg = replaced_reg.reg;
        }

        if (replaced_reg != null && !replaced_reg.no_use) {
            if (replaced_reg.mem == -1) {
                // 如果该变量内存中没有位置，push备份
                SymbolManager_.pushReg(dst_reg, 1);
                ASMLines.add(ASMConstructor.construct_asm("push", dst_reg));
            } else {
                // 如果该变量内存中有位置，直接更新该变量在内存中的值
                ASMLines.add(ASMConstructor.construct_asm("mov", replaced_reg.mem, replaced_reg.reg));
            }
        }

        if (TACLine_.dst.operType == TacOperandType.VAR) {
            String str_src1 = TACLine_.src1.value;
            if (TACLine_.src1.operType == TacOperandType.IMM) {
                // 如果 src1 是立即数
                ASMLines.add(ASMConstructor.construct_asm("mov", dst_reg, str_src1));
            } else if (TACLine_.src1.operType == TacOperandType.VAR) {
                // 如果 src1 是变量，可能会是寄存器、栈、全局变量
                String encode_str_src1 = SymbolManager_.encodeVar(str_src1);
                POSTYPE pos = SymbolManager_.position(encode_str_src1);
                if (pos == POSTYPE.REG) {
                    REG src_reg = SymbolManager_.avalueReg(encode_str_src1);
                    ASMLines.add(ASMConstructor.construct_asm("mov", dst_reg, src_reg));
                } else if (pos == POSTYPE.MEM) {
                    int src_mem = SymbolManager_.avalueMem(encode_str_src1);
                    ASMLines.add(ASMConstructor.construct_asm("mov", dst_reg, src_mem));
                } else if (pos == POSTYPE.GLOBAL) {
                    ASMLines.add(ASMConstructor.construct_asm("mov", dst_reg, str_src1));
                } else {
                    System.out.println("assign sentence: str1's pos wrong");
                }
            } else if (TACLine_.src1.operType == TacOperandType.PTR) {
                // 由于 TAC 对 operator[] 的处理，暂时可以认为这时指针一定在寄存器中
                String encode_str_src1 = SymbolManager_.encodeVar(str_src1);
                REG src_reg = SymbolManager_.avalueReg(encode_str_src1);
                ASMLines.add(ASMConstructor.construct_asm("mov", dst_reg, ASMConstructor.construct_asm_mem(src_reg, 0)));
            }
        } else if (TACLine_.dst.operType == TacOperandType.PTR) {
            String str_src1 = TACLine_.src1.getValue();
            if (TACLine_.src1.operType == TacOperandType.IMM) {
                // 如果 src1 是立即数
                ASMLines.add(ASMConstructor.construct_asm("mov", dst_reg, 0, str_src1));
            } else if (TACLine_.src1.operType == TacOperandType.VAR) {
                // 如果 src1 是变量，可能是寄存器、栈、全局变量
                String encode_str_src1 = SymbolManager_.encodeVar(str_src1);
                POSTYPE pos = SymbolManager_.position(encode_str_src1);
                if (pos == POSTYPE.REG) {
                    REG src_reg = SymbolManager_.avalueReg(encode_str_src1);
                    ASMLines.add(ASMConstructor.construct_asm("mov", dst_reg, 0, src_reg));
                } else if (pos == POSTYPE.MEM) {
                    int src_mem = SymbolManager_.avalueMem(encode_str_src1);
                    ASMLines.add(ASMConstructor.construct_asm("mov", dst_reg, 0, src_mem));
                } else if (pos == POSTYPE.GLOBAL) {
                    ASMLines.add(ASMConstructor.construct_asm("mov", dst_reg, 0, str_src1));
                } else {
                    System.out.println("assign sentence: str1's pos wrong");
                }
            } else if (TACLine_.src1.operType == TacOperandType.PTR) {
                // 由于 TAC 对 operator[] 的处理，暂时可以认为这时指针一定在寄存器中
                String encode_str_src1 = SymbolManager_.encodeVar(str_src1);
                REG src_reg = SymbolManager_.avalueReg(encode_str_src1);
                ASMLines.add(ASMConstructor.construct_asm("mov", ASMConstructor.construct_asm_mem(dst_reg, 0, "dword"), ASMConstructor.construct_asm_mem(src_reg, 0)));
            }
        } else System.out.println("assign sentence: dst' TacOperandType wrong");

        int dst_mem = SymbolManager_.avalueMem(str_dst_encode);
        if (dst_mem != -1) {
            ASMLines.add(ASMConstructor.construct_asm("mov", dst_mem, dst_reg));
        }

        // 更新 SymbolManager 中变量信息
        SymbolManager_.setAvalueReg(str_dst_encode, dst_reg);
        return ASMLines;
    }
}